home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 January / EnigmA AMIGA RUN 33 (1999)(G.R. Edizioni)(IT)[!][issue 1999-01].iso / earcd / apus / latest / bh981121.lha / bh981121 / linuxboot.c < prev    next >
C/C++ Source or Header  |  1997-02-22  |  51KB  |  1,884 lines

  1. /*
  2.  *  linux/arch/m68k/boot/amiga/linuxboot.c -- Generic routine to boot Linux/m68k
  3.  *                          on Amiga, used by both Amiboot and
  4.  *                          Amiga-Lilo.
  5.  *
  6.  *    Created 1996 by Geert Uytterhoeven
  7.  *
  8.  *
  9.  *  This file is based on the original bootstrap code (bootstrap.c):
  10.  *
  11.  *    Copyright (C) 1993, 1994 Hamish Macdonald
  12.  *                 Greg Harp
  13.  *
  14.  *            with work by Michael Rausch
  15.  *                 Geert Uytterhoeven
  16.  *                 Frank Neumann
  17.  *                 Andreas Schwab
  18.  *                 Jesper Skov
  19.  *
  20.  *
  21.  *  This file is subject to the terms and conditions of the GNU General Public
  22.  *  License.  See the file COPYING in the main directory of this archive
  23.  *  for more details.
  24.  *
  25.  *  History:
  26.  *    26 Feb 1998 Added support for booting APUS systems.
  27.  *    27 Mar 1997 FPU-less machines couldn't boot kernels that use bootinfo
  28.  *            interface version 1.0 (Geert)
  29.  *    03 Feb 1997 Implemented kernel decompression (Geert, based on Roman's
  30.  *            code for ataboot)
  31.  *    30 Dec 1996 Reverted the CPU detection to the old scheme
  32.  *            New boot parameter override scheme (Geert)
  33.  *      27 Nov 1996 Compatibility with bootinfo interface version 1.0 (Geert)
  34.  *       9 Sep 1996 Rewritten option parsing
  35.  *            New parameter passing to linuxboot() (linuxboot_args)
  36.  *            (Geert)
  37.  *    18 Aug 1996 Updated for the new boot information structure (Geert)
  38.  *    10 Jan 1996 The real Linux/m68k boot code moved to linuxboot.[ch]
  39.  *            (Geert)
  40.  *    11 Jul 1995 Support for ELF kernel (untested!) (Andreas)
  41.  *     7 Mar 1995 Memory block sizes are rounded to a multiple of 256K
  42.  *            instead of 1M (Geert)
  43.  *    31 May 1994 Memory thrash problem solved (Geert)
  44.  *    11 May 1994 A3640 MapROM check (Geert)
  45.  */
  46.  
  47.  
  48. #ifndef __GNUC__
  49. #error GNU CC is required to compile this program
  50. #endif /* __GNUC__ */
  51.  
  52.  
  53. #define BOOTINFO_COMPAT_1_0    /* bootinfo interface version 1.0 compatible */
  54. /* support compressed kernels? */
  55. #define ZKERNEL
  56.  
  57. #include <stddef.h>
  58. #include <string.h>
  59. #include <errno.h>
  60. #include <sys/types.h>
  61.  
  62. #include <linux/a.out.h>
  63. #include <linux/elf.h>
  64. #include <linux/linkage.h>
  65. #include <asm/bootinfo.h>
  66. #include <asm/amigahw.h>
  67. #include <asm/page.h>
  68.  
  69. #include "linuxboot.h"
  70.  
  71. #define APUS
  72. #ifdef APUS
  73.  
  74. #define INTUITION_CLASSES_H 1
  75.  
  76. #include <powerup/ppclib/interface.h>
  77. /*#include <powerup/gcclib/powerup_protos.h>*/
  78. #include <powerup/ppclib/message.h>
  79. #include <powerup/ppclib/tasks.h>
  80. #include <powerup/ppclib/object.h>
  81. #include "ppcboot_elf.h"
  82.  
  83. #endif
  84.  
  85. #undef custom
  86. #define custom ((*(volatile struct CUSTOM *)(CUSTOM_PHYSADDR)))
  87.  
  88. /* temporary stack size */
  89. #define TEMP_STACKSIZE    (256)
  90.  
  91. #define DEFAULT_BAUD    (9600)
  92.  
  93. extern char copyall, copyallend;
  94.  
  95. extern char getvbr, wedgie;
  96.  
  97. static struct exec kexec;
  98. static Elf32_Ehdr kexec_elf;
  99. static const struct linuxboot_args *linuxboot_args;
  100.  
  101. /* Bootinfo */
  102. struct amiga_bootinfo bi;
  103.  
  104. #ifdef BOOTINFO_COMPAT_1_0
  105. static struct compat_bootinfo compat_bootinfo;
  106. #endif /* BOOTINFO_COMPAT_1_0 */
  107.  
  108. #define MAX_BI_SIZE    (4096)
  109. static u_long bi_size;
  110. static union {
  111.     struct bi_record record;
  112.     u_char fake[MAX_BI_SIZE];
  113. } bi_union;
  114.  
  115. #define kernelname    linuxboot_args->kernelname
  116. #define ramdiskname    linuxboot_args->ramdiskname
  117. #define debugflag    linuxboot_args->debugflag
  118. #define keep_video    linuxboot_args->keep_video
  119. #define reset_boards    linuxboot_args->reset_boards
  120. #define baud        linuxboot_args->baud
  121.  
  122. #define apus_boot    linuxboot_args->apus_boot
  123. #define checksum    linuxboot_args->checksum
  124.  
  125. #define Puts        linuxboot_args->puts
  126. #define GetChar        linuxboot_args->getchar
  127. #define PutChar        linuxboot_args->putchar
  128. #define Printf        linuxboot_args->printf
  129. #define Open        linuxboot_args->open
  130. #define Seek        linuxboot_args->seek
  131. #define Read        linuxboot_args->read
  132. #define Close        linuxboot_args->close
  133. #define FileSize    linuxboot_args->filesize
  134. #define Sleep        linuxboot_args->sleep
  135.  
  136.     /*
  137.      *  Function Prototypes
  138.      */
  139.  
  140. static u_long get_chipset(void);
  141. static void get_processor(u_long *cpu, u_long *fpu, u_long *mmu);
  142. static u_long get_model(u_long chipset);
  143. static int probe_resident(const char *name);
  144. static int probe_resource(const char *name);
  145. static int create_bootinfo(void);
  146. #ifdef BOOTINFO_COMPAT_1_0
  147. static int create_compat_bootinfo(void);
  148. #endif /* BOOTINFO_COMPAT_1_0 */
  149. static int add_bi_record(u_short tag, u_short size, const void *data);
  150. static int add_bi_string(u_short tag, const u_char *s);
  151. static int check_bootinfo_version(const char *memptr);
  152. static void start_kernel(void (*startfunc)(), char *stackp, char *memptr,
  153.              u_long start_mem, u_long mem_size, u_long rd_size,
  154.              u_long kernel_size) __attribute__ ((noreturn));
  155. asmlinkage u_long maprommed(void);
  156. asmlinkage u_long check346(void);
  157. #ifdef ZKERNEL
  158. static int load_zkernel(int fd);
  159. static int KRead(int fd, void *buf, int cnt);
  160. static int KSeek(int fd, int offset);
  161. static int KClose(int fd);
  162. #else
  163. #define KRead        Read
  164. #define KSeek        Seek
  165. #define KClose        Close
  166. #endif
  167.  
  168.  
  169.     /*
  170.      *    Reset functions for nasty Zorro boards
  171.      */
  172.  
  173. static void reset_rb3(const struct ConfigDev *cd);
  174. static void reset_piccolo(const struct ConfigDev *cd);
  175. static void reset_sd64(const struct ConfigDev *cd);
  176. static void reset_a2065(const struct ConfigDev *cd);
  177. static void reset_ariadne(const struct ConfigDev *cd);
  178. static void reset_hydra(const struct ConfigDev *cd);
  179. #if 0
  180. static void reset_a2060(const struct ConfigDev *cd);
  181. #endif
  182.  
  183. struct boardreset {
  184.     u_short manuf;
  185.     u_short prod;
  186.     const char *name;
  187.     void (*reset)(const struct ConfigDev *cd);
  188. };
  189.  
  190. static struct boardreset boardresetdb[] = {
  191.     { MANUF_HELFRICH1, PROD_RAINBOW3, "Rainbow 3", reset_rb3 },
  192.     { MANUF_HELFRICH2, PROD_PICCOLO_REG, "Piccolo", reset_piccolo },
  193.     { MANUF_HELFRICH2, PROD_SD64_REG, "SD64", reset_sd64 },
  194.     { MANUF_COMMODORE, PROD_A2065, "A2065", reset_a2065 },
  195.     { MANUF_VILLAGE_TRONIC, PROD_ARIADNE, "Ariadne", reset_ariadne },
  196.     { MANUF_HYDRA_SYSTEMS, PROD_AMIGANET, "Hydra", reset_hydra },
  197. #if 0
  198.     { MANUF_COMMODORE, PROD_A2060, "A2060", reset_a2060 },
  199. #endif
  200. };
  201. #define NUM_BOARDRESET    sizeof(boardresetdb)/sizeof(*boardresetdb)
  202.  
  203. static void (*boardresetfuncs[ZORRO_NUM_AUTO])(const struct ConfigDev *cd);
  204.  
  205.  
  206. const char *amiga_models[] = {
  207.     "Amiga 500", "Amiga 500+", "Amiga 600", "Amiga 1000", "Amiga 1200",
  208.     "Amiga 2000", "Amiga 2500", "Amiga 3000", "Amiga 3000T", "Amiga 3000+",
  209.     "Amiga 4000", "Amiga 4000T", "CDTV", "CD32", "Draco"
  210. };
  211. const u_long first_amiga_model = AMI_500;
  212. const u_long last_amiga_model = AMI_DRACO;
  213.  
  214.  
  215. #define MASK(model)    (1<<AMI_##model)
  216.  
  217. #define CLASS_A3000    (MASK(3000) | MASK(3000T))
  218. #define CLASS_A4000    (MASK(4000) | MASK(4000T))
  219. #define CLASS_ZKICK    (MASK(500) | MASK(1000) | MASK(2000) | MASK(2500))
  220.  
  221.  
  222.     /*
  223.      *    Boot the Linux/m68k Operating System
  224.      */
  225.  
  226. u_long linuxboot(const struct linuxboot_args *args)
  227. {
  228.     int kfd = -1, rfd = -1, elf_kernel = 0, do_fast, do_chip;
  229.     int i, j;
  230.     const struct MemHeader *mnp;
  231.     struct ConfigDev *cdp = NULL;
  232.     char *memptr = NULL;
  233.     u_long *stack = NULL;
  234.     u_long fast_total, model_mask, startcodesize, start_mem, mem_size, rd_size;
  235.     u_long kernel_size;
  236.     u_int realbaud;
  237.     u_long memreq = 0, text_offset = 0;
  238.     Elf32_Phdr *kernel_phdrs = NULL;
  239.     void (*startfunc)(void);
  240.     u_short manuf;
  241.     u_char prod;
  242.     void *bi_ptr;
  243.     unsigned long* info;
  244.     struct ConfigDev *zdevs[ZORRO_NUM_AUTO];
  245.  
  246.     linuxboot_args = args;
  247.  
  248.     /* print the greet message */
  249.     Puts("\nLinux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n");
  250.     Puts("Copyright 1993,1994 by Hamish Macdonald and Greg Harp\n\n");
  251.  
  252.     /* Note: Initial values in bi override detected values */
  253.     bi = args->bi;
  254.  
  255.     /* machine is Amiga */
  256.     bi.machtype = MACH_AMIGA;
  257.  
  258.     /* determine chipset */
  259.     if (!bi.chipset)
  260.     bi.chipset = get_chipset();
  261.  
  262.     /* determine CPU, FPU and MMU type */
  263.     if (!bi.cputype)
  264.     get_processor(&bi.cputype, &bi.fputype, &bi.mmutype);
  265.  
  266.     /* determine Amiga model */
  267.     if (!bi.model)
  268.     bi.model = get_model(bi.chipset);
  269.     model_mask = (bi.model != AMI_UNKNOWN) ? 1<<bi.model : 0;
  270.  
  271.     /* Memory & AutoConfig based on 'unix_boot.c' by C= */
  272.  
  273.     /* find all of the autoconfig boards in the system */
  274.     if (!bi.num_autocon)
  275.     for (i = 0; (cdp = (struct ConfigDev *)FindConfigDev(cdp, -1, -1)); i++)
  276.         if (bi.num_autocon < ZORRO_NUM_AUTO) {
  277.         zdevs[i] = cdp;
  278.         /* copy the contents of each structure into our boot info and
  279.            count this device */
  280.         memcpy(&bi.autocon[bi.num_autocon++], cdp,
  281.                sizeof(struct ConfigDev));
  282.         } else
  283.         Printf("Warning: too many AutoConfig devices. Ignoring device "
  284.                "at 0x%08lx\n", cdp->cd_BoardAddr);
  285.  
  286.     do_fast = bi.num_memory ? 0 : 1;
  287.     do_chip = bi.chip_size ? 0 : 1;
  288.     /* find out the memory in the system */
  289.     for (mnp = (struct MemHeader *)SysBase->MemList.lh_Head;
  290.      mnp->mh_Node.ln_Succ;
  291.      mnp = (struct MemHeader *)mnp->mh_Node.ln_Succ) {
  292.     struct MemHeader mh;
  293.  
  294.     /* copy the information */
  295.     mh = *mnp;
  296.  
  297.     /* skip virtual memory */
  298.     if (!(mh.mh_Attributes & MEMF_PUBLIC))
  299.         continue;
  300.  
  301.     /* if we suspect that Kickstart is shadowed in an A3000,
  302.        modify the entry to show 512K more at the top of RAM
  303.        Check first for a MapROMmed A3640 board: overwriting the
  304.        Kickstart image causes an infinite lock-up on reboot! */
  305.     if ((mh.mh_Upper == (void *)0x07f80000) &&
  306.         (model_mask & (CLASS_A3000 | CLASS_A4000)))
  307.         if ((bi.cputype & CPU_68040) && Supervisor(maprommed))
  308.         Puts("A3640 MapROM detected.\n");
  309.         else if (model_mask & CLASS_A3000) {
  310.         mh.mh_Upper = (void *)0x08000000;
  311.         Puts("A3000 shadowed Kickstart detected.\n");
  312.         }
  313.  
  314.     /* if we suspect that Kickstart is zkicked,
  315.        modify the entry to show 512K more at the botton of RAM */
  316.     if ((mh.mh_Lower == (void *)0x00280020) &&
  317.         (model_mask & CLASS_ZKICK)) {
  318.         mh.mh_Lower = (void *)0x00200000;
  319.         Puts("ZKick detected.\n");
  320.     }
  321.  
  322.     /* mask the memory limit values */
  323.     mh.mh_Upper = (void *)((u_long)mh.mh_Upper & 0xfffff000);
  324.     mh.mh_Lower = (void *)((u_long)mh.mh_Lower & 0xfffff000);
  325.  
  326.     /* if fast memory */
  327.     if (do_fast && mh.mh_Attributes & MEMF_FAST) {
  328.         /* set the size value to the size of this block and mask off to a
  329.            256K increment */
  330.         u_long size = ((u_long)mh.mh_Upper-(u_long)mh.mh_Lower)&0xfffc0000;
  331.         if (size > 0)
  332.         if (bi.num_memory < NUM_MEMINFO) {
  333.             /* record the start and size */
  334.             bi.memory[bi.num_memory].addr = (u_long)mh.mh_Lower;
  335.             bi.memory[bi.num_memory].size = size;
  336.             /* count this block */
  337.             bi.num_memory++;
  338.         } else
  339.             Printf("Warning: too many memory blocks. Ignoring block "
  340.                    "of %ldK at 0x%08x\n", size>>10,
  341.                (u_long)mh.mh_Lower);
  342.     } else if (do_chip && mh.mh_Attributes & MEMF_CHIP)
  343.         /* if CHIP memory, record the size */
  344.         bi.chip_size = (u_long)mh.mh_Upper;
  345.     }
  346.  
  347.     /* get info from ExecBase */
  348.     if (!bi.vblank)
  349.     bi.vblank = SysBase->VBlankFrequency;
  350.     if (!bi.psfreq)
  351.     bi.psfreq = SysBase->PowerSupplyFrequency;
  352.     if (!bi.eclock)
  353.     bi.eclock = SysBase->ex_EClockFrequency;
  354.  
  355.     /* serial port */
  356.     if (!bi.serper) {
  357.     realbaud = baud ? baud : DEFAULT_BAUD;
  358.     bi.serper = (5*bi.eclock+realbaud/2)/realbaud-1;
  359.     }
  360.  
  361.     /* display Amiga model */
  362.     if (bi.model >= first_amiga_model && bi.model <= last_amiga_model)
  363.     Printf("%s ", amiga_models[bi.model-first_amiga_model]);
  364.     else
  365.     Puts("Amiga ");
  366.  
  367.     /* display the CPU type */
  368.     Puts("CPU: ");
  369.     switch (bi.cputype) {
  370.     case CPU_68020:
  371.         Puts("68020 (Do you have an MMU?)");
  372.         break;
  373.     case CPU_68030:
  374.         Puts("68030");
  375.         break;
  376.     case CPU_68040:
  377.         Puts("68040");
  378.         break;
  379.     case CPU_68060:
  380.         Puts("68060");
  381.         break;
  382.     default:
  383.         Puts("Insufficient for Linux.  Aborting...\n");
  384.         Printf("SysBase->AttnFlags = 0x%08lx\n", SysBase->AttnFlags);
  385.         goto Fail;
  386.     }
  387.     switch (bi.fputype) {
  388.     case FPU_68881:
  389.         Puts(" with 68881 FPU");
  390.         break;
  391.     case FPU_68882:
  392.         Puts(" with 68882 FPU");
  393.         break;
  394.     case FPU_68040:
  395.     case FPU_68060:
  396.         Puts(" with internal FPU");
  397.         break;
  398.     default:
  399.         Puts(" without FPU");
  400.         break;
  401.     }
  402.  
  403.     /* display the chipset */
  404.     switch (bi.chipset) {
  405.     case CS_STONEAGE:
  406.         Puts(", old or unknown chipset");
  407.         break;
  408.     case CS_OCS:
  409.         Puts(", OCS");
  410.         break;
  411.     case CS_ECS:
  412.         Puts(", ECS");
  413.         break;
  414.     case CS_AGA:
  415.         Puts(", AGA chipset");
  416.         break;
  417.     }
  418.  
  419.     Puts("\n\n");
  420.  
  421.     /* display the command line */
  422.     Printf("Command line is '%s'\n", bi.command_line);
  423.  
  424.     /* display the clock statistics */
  425.     Printf("Vertical Blank Frequency: %ldHz\n", bi.vblank);
  426.     Printf("Power Supply Frequency: %ldHz\n", bi.psfreq);
  427.     Printf("EClock Frequency: %ldHz\n\n", bi.eclock);
  428.  
  429.     /* display autoconfig devices */
  430.     if (bi.num_autocon) {
  431.     Printf("Found %ld AutoConfig Device%s\n", bi.num_autocon,
  432.            bi.num_autocon > 1 ? "s" : "");
  433.     for (i = 0; i < bi.num_autocon; i++) {
  434.         Printf("Device %ld: addr = 0x%08lx", i,
  435.            (u_long)zdevs[i]->cd_BoardAddr);
  436.         boardresetfuncs[i] = NULL;
  437.         if (reset_boards) {
  438.         manuf = zdevs[i]->cd_Rom.er_Manufacturer;
  439.         prod = zdevs[i]->cd_Rom.er_Product;
  440.         for (j = 0; j < NUM_BOARDRESET; j++)
  441.             if ((manuf == boardresetdb[j].manuf) &&
  442.             (prod == boardresetdb[j].prod)) {
  443.             Printf(" [%s - will be reset at kernel boot time]",
  444.                    boardresetdb[j].name);
  445.             boardresetfuncs[i] = boardresetdb[j].reset;
  446.             break;
  447.             }
  448.         }
  449.         PutChar('\n');
  450.     }
  451.     } else
  452.     Puts("No AutoConfig Devices Found\n");
  453.  
  454.     /* display memory */
  455.     if (bi.num_memory) {
  456.     Printf("\nFound %ld Block%sof Memory\n", bi.num_memory,
  457.            bi.num_memory > 1 ? "s " : " ");
  458.     for (i = 0; i < bi.num_memory; i++)
  459.         Printf("Block %ld: 0x%08lx to 0x%08lx (%ldK)\n", i,
  460.            bi.memory[i].addr, bi.memory[i].addr+bi.memory[i].size,
  461.            bi.memory[i].size>>10);
  462.     } else {
  463.     Puts("No memory found?!  Aborting...\n");
  464.     goto Fail;
  465.     }
  466.  
  467.     /* display chip memory size */
  468.     Printf("%ldK of CHIP memory\n", bi.chip_size>>10);
  469.  
  470.     start_mem = bi.memory[0].addr;
  471.     mem_size = bi.memory[0].size;
  472.  
  473.     /* tell us where the kernel will go */
  474.     Printf("\nThe kernel will be located at 0x%08lx\n", start_mem);
  475.  
  476.     /* verify that there is enough Chip RAM */
  477.     if (bi.chip_size < 512*1024) {
  478.     Puts("Not enough Chip RAM in this system.  Aborting...\n");
  479.     goto Fail;
  480.     }
  481.  
  482.     /* verify that there is enough Fast RAM */
  483.     for (fast_total = 0, i = 0; i < bi.num_memory; i++)
  484.     fast_total += bi.memory[i].size;
  485.     if (fast_total < 2*1024*1024) {
  486.     Puts("Not enough Fast RAM in this system.  Aborting...\n");
  487.     goto Fail;
  488.     }
  489.  
  490.     /* support for ramdisk */
  491.     if (ramdiskname) {
  492.     int size;
  493.  
  494.     if ((size = FileSize(ramdiskname)) == -1) {
  495.         Printf("Unable to find size of ramdisk file `%s'\n", ramdiskname);
  496.         goto Fail;
  497.     }
  498.     /* record ramdisk size */
  499.     bi.ramdisk.size = size;
  500.     } else
  501.     bi.ramdisk.size = 0;
  502.     rd_size = bi.ramdisk.size;
  503.     bi.ramdisk.addr = (u_long)start_mem+mem_size-rd_size;
  504.  
  505.     /* create the bootinfo structure */
  506.     if (!create_bootinfo())
  507.     goto Fail;
  508.  
  509.     /* open kernel executable and read exec header */
  510.     if ((kfd = Open(kernelname)) == -1) {
  511.     Printf("Unable to open kernel file `%s'\n", kernelname);
  512.     goto Fail;
  513.     }
  514.     if (KRead(kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) {
  515.     Puts("Unable to read exec header from kernel file\n");
  516.     goto Fail;
  517.     }
  518.  
  519. #ifdef ZKERNEL
  520.     if (((unsigned char *)&kexec)[0] == 037 &&
  521.     (((unsigned char *)&kexec)[1] == 0213 ||
  522.      ((unsigned char *)&kexec)[1] == 0236)) {
  523.     /* That's a compressed kernel */
  524.     Puts("Kernel is compressed\n");
  525.     if (load_zkernel(kfd)) {
  526.         Puts("Decompression error -- aborting\n");
  527.         goto Fail;
  528.     }
  529.     }
  530. #endif
  531.  
  532.     switch (N_MAGIC(kexec)) {
  533.     case ZMAGIC:
  534.         if (debugflag)
  535.         Puts("\nLoading a.out (ZMAGIC) Linux/m68k kernel...\n");
  536.         text_offset = N_TXTOFF(kexec);
  537.         break;
  538.  
  539.     case QMAGIC:
  540.         if (debugflag)
  541.         Puts("\nLoading a.out (QMAGIC) Linux/m68k kernel...\n");
  542.         text_offset = sizeof(kexec);
  543.         /* the text size includes the exec header; remove this */
  544.         kexec.a_text -= sizeof(kexec);
  545.         break;
  546.  
  547.     default:
  548.         /* Try to parse it as an ELF header */
  549.         KSeek(kfd, 0);
  550.         if ((KRead(kfd, (void *)&kexec_elf, sizeof(kexec_elf)) ==
  551.          sizeof(kexec_elf)) &&
  552.          (memcmp(&kexec_elf.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0)) {
  553.         elf_kernel = 1;
  554.         if (debugflag)
  555.             Puts("\nLoading ELF Linux/m68k kernel...\n");
  556.         /* A few plausibility checks */
  557.         if ((kexec_elf.e_type != ET_EXEC) ||
  558.             (kexec_elf.e_machine != EM_PPC && apus_boot) ||
  559.             (kexec_elf.e_machine != EM_68K && !apus_boot) ||
  560.             (kexec_elf.e_version != EV_CURRENT)) {
  561.             Puts("Invalid ELF header contents in kernel\n");
  562.             Printf("machine : %d, type: %d, version: %d\n",
  563.              kexec_elf.e_machine, kexec_elf.e_type, kexec_elf.e_version);
  564.             goto Fail;
  565.         }
  566.         /* Load the program headers */
  567.         if (!(kernel_phdrs =
  568.               (Elf32_Phdr *)AllocMem(kexec_elf.e_phnum*sizeof(Elf32_Phdr),
  569.                          MEMF_FAST | MEMF_PUBLIC |
  570.                          MEMF_CLEAR))) {
  571.             Puts("Unable to allocate memory for program headers\n");
  572.             goto Fail;
  573.         }
  574.         KSeek(kfd, kexec_elf.e_phoff);
  575.         if (KRead(kfd, (void *)kernel_phdrs,
  576.              kexec_elf.e_phnum*sizeof(*kernel_phdrs)) !=
  577.             kexec_elf.e_phnum*sizeof(*kernel_phdrs)) {
  578.             Puts("Unable to read program headers from kernel file\n");
  579.             goto Fail;
  580.         }
  581.         break;
  582.         }
  583.         Printf("Wrong magic number 0x%08lx in kernel header\n",
  584.            N_MAGIC(kexec));
  585.         goto Fail;
  586.     }
  587.  
  588.     /* Load the kernel at one page after start of mem */
  589.     if (!apus_boot) {
  590.     start_mem += PAGE_SIZE;
  591.     mem_size -= PAGE_SIZE;
  592.     }
  593.  
  594.     /* Align bss size to multiple of four */
  595.     if (!elf_kernel)
  596.     kexec.a_bss = (kexec.a_bss+3) & ~3;
  597.  
  598.     /* calculate the total required amount of memory */
  599.     if (elf_kernel) {
  600.     u_long min_addr = 0xffffffff, max_addr = 0;
  601.     for (i = 0; i < kexec_elf.e_phnum; i++) {
  602.         if (min_addr > kernel_phdrs[i].p_vaddr)
  603.         min_addr = kernel_phdrs[i].p_vaddr;
  604.         if (max_addr < kernel_phdrs[i].p_vaddr+kernel_phdrs[i].p_memsz)
  605.         max_addr = kernel_phdrs[i].p_vaddr+kernel_phdrs[i].p_memsz;
  606.     }
  607.     /* This is needed for newer linkers that include the header in
  608.        the first segment.  */
  609.     if (apus_boot) {
  610.         /* Avoid ugly hacks further down. */
  611.         kernel_phdrs[0].p_vaddr = PAGE_SIZE;
  612.     } else if (min_addr == 0) {
  613.         min_addr = PAGE_SIZE;
  614.         kernel_phdrs[0].p_vaddr += PAGE_SIZE;
  615.         kernel_phdrs[0].p_offset += PAGE_SIZE;
  616.         kernel_phdrs[0].p_filesz -= PAGE_SIZE;
  617.         kernel_phdrs[0].p_memsz -= PAGE_SIZE;
  618.     }
  619.     kernel_size = max_addr-min_addr;
  620.     } else
  621.     kernel_size = kexec.a_text+kexec.a_data+kexec.a_bss;
  622.     memreq = kernel_size+bi_size+rd_size;
  623. #ifdef BOOTINFO_COMPAT_1_0
  624.     if (sizeof(compat_bootinfo) > bi_size)
  625.     memreq = kernel_size+sizeof(compat_bootinfo)+rd_size;
  626. #endif /* BOOTINFO_COMPAT_1_0 */
  627.     if (!(memptr = (char *)AllocMem(memreq, MEMF_FAST | MEMF_PUBLIC |
  628.                         MEMF_CLEAR))) {
  629.     Puts("Unable to allocate memory\n");
  630.     goto Fail;
  631.     }
  632.  
  633.     /* read the text and data segments from the kernel image */
  634.     if (elf_kernel)
  635.     for (i = 0; i < kexec_elf.e_phnum; i++) {
  636.         if (KSeek(kfd, kernel_phdrs[i].p_offset) == -1) {
  637.         Printf("Failed to seek to segment %ld\n", i);
  638.         goto Fail;
  639.         }
  640.         if (KRead(kfd, memptr+kernel_phdrs[i].p_vaddr-PAGE_SIZE,
  641.               kernel_phdrs[i].p_filesz) != kernel_phdrs[i].p_filesz) {
  642.         Printf("Failed to read segment %ld\n", i);
  643.         goto Fail;
  644.         }
  645.     }
  646.     else {
  647.     if (KSeek(kfd, text_offset) == -1) {
  648.         Puts("Failed to seek to text\n");
  649.         goto Fail;
  650.     }
  651.     if (KRead(kfd, memptr, kexec.a_text) != kexec.a_text) {
  652.         Puts("Failed to read text\n");
  653.         goto Fail;
  654.     }
  655.     /* data follows immediately after text */
  656.     if (KRead(kfd, memptr+kexec.a_text, kexec.a_data) != kexec.a_data) {
  657.         Puts("Failed to read data\n");
  658.         goto Fail;
  659.     }
  660.     }
  661.     KClose(kfd);
  662.     kfd = -1;
  663.  
  664.     /* Check kernel's bootinfo version */
  665.     switch (apus_boot ? BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION) :
  666.         check_bootinfo_version(memptr)) {
  667.     case BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION):
  668.         bi_ptr = &bi_union.record;
  669.         break;
  670.  
  671. #ifdef BOOTINFO_COMPAT_1_0
  672.     case BI_VERSION_MAJOR(COMPAT_AMIGA_BOOTI_VERSION):
  673.         if (!create_compat_bootinfo())
  674.         goto Fail;
  675.         bi_ptr = &compat_bootinfo;
  676.         bi_size = sizeof(compat_bootinfo);
  677.         break;
  678. #endif /* BOOTINFO_COMPAT_1_0 */
  679.  
  680.     default:
  681.         goto Fail;
  682.     }
  683.  
  684.     /* copy the bootinfo to the end of the kernel image */
  685.     memcpy((void *)(memptr+kernel_size), bi_ptr, bi_size);
  686.  
  687.     if (ramdiskname) {
  688.     if ((rfd = Open(ramdiskname)) == -1) {
  689.         Printf("Unable to open ramdisk file `%s'\n", ramdiskname);
  690.         goto Fail;
  691.     }
  692.     if (Read(rfd, memptr+kernel_size+bi_size, rd_size) != rd_size) {
  693.         Puts("Failed to read ramdisk file\n");
  694.         goto Fail;
  695.     }
  696.     Close(rfd);
  697.     rfd = -1;
  698.     }
  699.  
  700.     /* allocate temporary chip ram stack */
  701.     if (!(stack = (u_long *)AllocMem(TEMP_STACKSIZE, MEMF_CHIP | MEMF_CLEAR))) {
  702.     Puts("Unable to allocate memory for stack\n");
  703.     goto Fail;
  704.     }
  705.  
  706.     /* allocate chip ram for copy of startup code */
  707.     startcodesize = ©allend-©all;
  708.     if (!(startfunc = (void (*)(void))AllocMem(startcodesize,
  709.                            MEMF_CHIP | MEMF_CLEAR))) {
  710.     Puts("Unable to allocate memory for startcode\n");
  711.     goto Fail;
  712.     }
  713.  
  714.     /* copy startup code to CHIP RAM */
  715.     memcpy(startfunc, ©all, startcodesize);
  716.  
  717.     if (debugflag) {
  718.     if (bi.ramdisk.size)
  719.         Printf("RAM disk at 0x%08lx, size is %ldK\n",
  720.            (u_long)memptr+kernel_size, bi.ramdisk.size>>10);
  721.  
  722.     if (elf_kernel) {
  723.         PutChar('\n');
  724.         for (i = 0; i < kexec_elf.e_phnum; i++)
  725.         Printf("Kernel segment %ld at 0x%08lx, size %ld\n", i,
  726.                start_mem+kernel_phdrs[i].p_vaddr-PAGE_SIZE,
  727.                kernel_phdrs[i].p_memsz);
  728.         Printf("Boot info        at 0x%08lx\n", start_mem+kernel_size);
  729.     } else {
  730.         Printf("\nKernel text at 0x%08lx, code size 0x%08lx\n", start_mem,
  731.            kexec.a_text);
  732.         Printf("Kernel data at 0x%08lx, data size 0x%08lx\n",
  733.            start_mem+kexec.a_text, kexec.a_data);
  734.         Printf("Kernel bss  at 0x%08lx, bss  size 0x%08lx\n",
  735.            start_mem+kexec.a_text+kexec.a_data, kexec.a_bss);
  736.         Printf("Boot info   at 0x%08lx\n", start_mem+kernel_size);
  737.     }
  738.     Printf("\nKernel entry is 0x%08lx\n", elf_kernel ? kexec_elf.e_entry :
  739.                                kexec.a_entry);
  740.  
  741.     Printf("ramdisk dest top is 0x%08lx\n", start_mem+mem_size);
  742.     Printf("ramdisk lower limit is 0x%08lx\n",
  743.            (u_long)(memptr+kernel_size));
  744.     Printf("ramdisk src top is 0x%08lx\n",
  745.            (u_long)(memptr+kernel_size)+rd_size);
  746.  
  747.     Puts("\nType a key to continue the Linux/m68k boot...");
  748.     GetChar();
  749.     PutChar('\n');
  750.     }
  751.  
  752.     /* wait for things to settle down */
  753.     Sleep(1000000);
  754.  
  755.  
  756.     {
  757.         void* PPCPort;
  758.         void* PPCMsg;
  759.  
  760. #define CHIP_PTR (0xfff00)
  761. #define INFO_SIZE (0x3000 + 0x0100)
  762.     if (apus_boot) {
  763.         /* Let the PowerPC handle the actual kernel start */
  764.     
  765.         /* Store some relevant information about the kernel image
  766.          * and RAM disk at *CHIP_PTR.
  767.          */
  768.         unsigned long boot_msg;
  769.         
  770.         /* Make sure the CHIP_PTR will not be destroyed. */
  771.         if (!AllocAbs (0x10, CHIP_PTR)){
  772.             Puts("Unable to allocate CHIP memory at 0xfff00.\n"
  773.                  "Try booting with a smaller resolution.\n");
  774.         }
  775.         
  776.         if (!(boot_msg = (unsigned long) AllocMem (0x200, 
  777.                                                    MEMF_REVERSE 
  778.                                                    | MEMF_CHIP 
  779.                                                    | MEMF_CLEAR))){
  780.                                                    
  781.             Puts("Unable to allocate CHIP memory for boot message\n");
  782.             goto Fail;
  783.         }
  784.  
  785.         if (!(info = (unsigned long*) AllocMem (INFO_SIZE, 
  786.                                                 MEMF_CHIP | MEMF_CLEAR))){
  787.             Puts("Unable to allocate CHIP memory for info table and"
  788.                  " reloc code\n");
  789.             goto Fail;
  790.         }        
  791.  
  792.         /* Leave the pointer in chip mem at address CHIP_PTR. */
  793.         *((unsigned long*) CHIP_PTR) = (unsigned long) info;
  794.         info[0] = (unsigned long) (memptr+kernel_phdrs[0].p_vaddr-PAGE_SIZE);
  795.         info[1] = start_mem;
  796.         info[2] = kernel_size;
  797.         info[3] = bi_size;
  798.         info[4] = rd_size;
  799.         info[5] = mem_size;
  800.         info[6] = boot_msg + 0x100;
  801.         info[7] = 0; /* checksum */
  802.         info[8] = (unsigned long)info + 0x2000; /* stack */
  803.         
  804.         /* Calculate a simple kernel checksum. */
  805.         if (checksum)
  806.         {
  807.             int i = (info[2] + info[3]) / 4;
  808.             unsigned char* k_p = (unsigned char*) info[0];
  809.             unsigned long kcs = 0;
  810.             
  811.             while (i--)
  812.             {
  813.                 unsigned long w = 0;
  814.                 
  815.                 w |= *k_p++;
  816.                 w <<= 8;
  817.                 w |= *k_p++;
  818.                 w <<= 8;
  819.                 w |= *k_p++;
  820.                 w <<= 8;
  821.                 w |= *k_p++;
  822.  
  823.                 
  824.                 kcs = kcs ^ i;
  825.                 kcs = kcs ^ w;
  826.             }
  827.             info[7] = kcs;
  828.         }
  829.         
  830.         /* Set LVL7 vector ("expose the top rim of our shorts") */
  831.         {
  832.             unsigned long* vbr;
  833.  
  834.             vbr = (unsigned long*) Supervisor((void*)&getvbr);
  835.             vbr[31] = (unsigned long) &wedgie;
  836.         }
  837.         
  838.         
  839.         {
  840.             void* elfObject;
  841.             void* task;
  842.             struct TagItem MyTags[2];
  843.             struct TagItem tag;
  844.             
  845.             /* Load PPC elf object. */
  846.             MyTags[0].ti_Tag    =    PPCELFLOADTAG_ELFADDRESS;
  847.             MyTags[0].ti_Data    =    (u_long)myppc_boot;
  848.             MyTags[1].ti_Tag    =    TAG_DONE;
  849.         
  850.             elfObject = (void*) PPCLoadObjectTagList(MyTags);
  851.         
  852.             /* Start PPC code, asking for a MSGPORT to be created. */
  853.             MyTags[0].ti_Tag    =    PPCTASKTAG_MSGPORT;
  854.             MyTags[0].ti_Data    =    TRUE;
  855.             MyTags[1].ti_Tag    =    TAG_DONE;
  856.             task = PPCCreateTask(elfObject, MyTags);
  857.  
  858.             tag.ti_Tag = PPCTASKINFOTAG_MSGPORT;
  859.             if (PPCPort=(void*) PPCGetTaskAttrs(task, &tag))
  860.             {
  861.                 PPCMsg = PPCCreateMessage(NULL, 0);
  862.             }
  863.  
  864.             
  865.             if (PPCPort == 0 || PPCMsg == 0)
  866.             {
  867.                 Puts ("Didn't get contact with PPC task...\n");
  868.                 goto Fail;
  869.             }
  870.         }
  871.     }
  872.  
  873.     /* turn off caches */
  874.     CacheControl(0, ~0);
  875.     
  876.     if (!keep_video)
  877.     /* set graphics mode to a nice normal one */
  878.     LoadView(NULL);
  879.  
  880.     /* reset nasty Zorro boards */
  881.     if (reset_boards)
  882.     for (i = 0; i < bi.num_autocon; i++)
  883.         if (boardresetfuncs[i])
  884.             boardresetfuncs[i](zdevs[i]);
  885.  
  886.     if (apus_boot && PPCPort && PPCMsg)
  887.     {
  888.         /* Notify the PPC that we are done ("bend over") */
  889.         PPCSendMessage(PPCPort, PPCMsg,    NULL, 0, 0);
  890.         for (;;) ;
  891.     }
  892.  
  893.     /* Go into supervisor state */
  894.     SuperState();
  895.  
  896.     }
  897.     /* Turn off interrupts. */
  898.     Disable();
  899.  
  900.     /* Turn off all DMA */
  901.     custom.dmacon = DMAF_ALL | DMAF_MASTER;
  902.     
  903.     /* turn off any mmu translation */
  904.     disable_mmu();
  905.  
  906.     /* execute the copy-and-go code (from CHIP RAM) */
  907.     start_kernel(startfunc, (char *)stack+TEMP_STACKSIZE, memptr, start_mem,
  908.          mem_size, rd_size, kernel_size);
  909.  
  910.     /* Clean up and exit in case of a failure */
  911. Fail:
  912.     if (kfd != -1)
  913.     KClose(kfd);
  914.     if (rfd != -1)
  915.     Close(rfd);
  916.     if (info)
  917.     FreeMem((void *) info, INFO_SIZE);
  918.     if (memptr)
  919.     FreeMem((void *)memptr, memreq);
  920.     if (stack)
  921.     FreeMem((void *)stack, TEMP_STACKSIZE);
  922.     if (kernel_phdrs)
  923.     FreeMem((void *)kernel_phdrs, kexec_elf.e_phnum*sizeof(Elf32_Phdr));
  924.     return(FALSE);
  925. }
  926.  
  927.  
  928.     /*
  929.      *    Determine the Chipset
  930.      */
  931.  
  932. static u_long get_chipset(void)
  933. {
  934.     u_char cs;
  935.     u_long chipset;
  936.  
  937.     if (GfxBase->Version >= 39)
  938.     cs = SetChipRev(SETCHIPREV_BEST);
  939.     else
  940.     cs = GfxBase->ChipRevBits0;
  941.     if ((cs & GFXG_AGA) == GFXG_AGA)
  942.     chipset = CS_AGA;
  943.     else if ((cs & GFXG_ECS) == GFXG_ECS)
  944.     chipset = CS_ECS;
  945.     else if ((cs & GFXG_OCS) == GFXG_OCS)
  946.     chipset = CS_OCS;
  947.     else
  948.     chipset = CS_STONEAGE;
  949.     return(chipset);
  950. }
  951.  
  952.  
  953.     /*
  954.      *    Determine the CPU Type
  955.      */
  956.  
  957. static void get_processor(u_long *cpu, u_long *fpu, u_long *mmu)
  958. {
  959.     *cpu = *fpu = 0;
  960.  
  961.     if (SysBase->AttnFlags & AFF_68060)
  962.     *cpu = CPU_68060;
  963.     else if (SysBase->AttnFlags & AFF_68040)
  964.     *cpu = CPU_68040;
  965.     else if (SysBase->AttnFlags & AFF_68030)
  966.     *cpu = CPU_68030;
  967.     else if (SysBase->AttnFlags & AFF_68020)
  968.     *cpu = CPU_68020;
  969.  
  970.     if (*cpu == CPU_68040 || *cpu == CPU_68060) {
  971.     if (SysBase->AttnFlags & AFF_FPU40)
  972.         *fpu = *cpu;
  973.     } else if (SysBase->AttnFlags & AFF_68882)
  974.     *fpu = FPU_68882;
  975.     else if (SysBase->AttnFlags & AFF_68881)
  976.     *fpu = FPU_68881;
  977.  
  978.     *mmu = *cpu;
  979. }
  980.  
  981.     /*
  982.      *    Determine the Amiga Model
  983.      */
  984.  
  985. static u_long get_model(u_long chipset)
  986. {
  987.     u_long model = AMI_UNKNOWN;
  988.  
  989.     if (debugflag)
  990.     Puts("Amiga model identification:\n");
  991.     if (probe_resource("draco.resource"))
  992.     model = AMI_DRACO;
  993.     else {
  994.     if (debugflag)
  995.         Puts("    Chipset: ");
  996.     switch (chipset) {
  997.         case CS_STONEAGE:
  998.         if (debugflag)
  999.             Puts("Old or unknown\n");
  1000.         goto OCS;
  1001.         break;
  1002.  
  1003.         case CS_OCS:
  1004.         if (debugflag)
  1005.             Puts("OCS\n");
  1006. OCS:        if (probe_resident("cd.device"))
  1007.             model = AMI_CDTV;
  1008.         else
  1009.             /* let's call it an A2000 (may be A500, A1000, A2500) */
  1010.             model = AMI_2000;
  1011.         break;
  1012.  
  1013.         case CS_ECS:
  1014.         if (debugflag)
  1015.             Puts("ECS\n");
  1016.         if (probe_resident("Magic 36.7") ||
  1017.             probe_resident("kickad 36.57") ||
  1018.             probe_resident("A3000 Bonus") ||
  1019.             probe_resident("A3000 bonus"))
  1020.             /* let's call it an A3000 (may be A3000T) */
  1021.             model = AMI_3000;
  1022.         else if (probe_resource("card.resource"))
  1023.             model = AMI_600;
  1024.         else
  1025.             /* let's call it an A2000 (may be A500[+], A1000, A2500) */
  1026.             model = AMI_2000;
  1027.         break;
  1028.  
  1029.         case CS_AGA:
  1030.         if (debugflag)
  1031.             Puts("AGA\n");
  1032.         if (probe_resident("A1000 Bonus") ||
  1033.             probe_resident("A4000 bonus"))
  1034.             model = probe_resident("NCR scsi.device") ? AMI_4000T :
  1035.                                 AMI_4000;
  1036.         else if (probe_resource("card.resource"))
  1037.             model = AMI_1200;
  1038.         else if (probe_resident("cd.device"))
  1039.             model = AMI_CD32;
  1040.         else
  1041.             model = AMI_3000PLUS;
  1042.         break;
  1043.     }
  1044.     }
  1045.     if (debugflag) {
  1046.     Puts("\nType a key to continue...");
  1047.     GetChar();
  1048.     Puts("\n\n");
  1049.     }
  1050.     return(model);
  1051. }
  1052.  
  1053.  
  1054.     /*
  1055.      *    Probe for a Resident Modules
  1056.      */
  1057.  
  1058. static int probe_resident(const char *name)
  1059. {
  1060.     const struct Resident *res;
  1061.  
  1062.     if (debugflag)
  1063.     Printf("    Module `%s': ", name);
  1064.     res = FindResident(name);
  1065.     if (debugflag)
  1066.     if (res)
  1067.         Printf("0x%08lx\n", res);
  1068.     else
  1069.         Puts("not present\n");
  1070.     return(res ? TRUE : FALSE);
  1071. }
  1072.  
  1073.  
  1074.     /*
  1075.      *    Probe for an available Resource
  1076.      */
  1077.  
  1078. static int probe_resource(const char *name)
  1079. {
  1080.     const void *res;
  1081.  
  1082.     if (debugflag)
  1083.     Printf("    Resource `%s': ", name);
  1084.     res = OpenResource(name);
  1085.     if (debugflag)
  1086.     if (res)
  1087.         Printf("0x%08lx\n", res);
  1088.     else
  1089.         Puts("not present\n");
  1090.     return(res ? TRUE : FALSE);
  1091. }
  1092.  
  1093.  
  1094.     /*
  1095.      *  Create the Bootinfo structure
  1096.      */
  1097.  
  1098. static int create_bootinfo(void)
  1099. {
  1100.     int i;
  1101.     struct bi_record *record;
  1102.  
  1103.     /* Initialization */
  1104.     bi_size = 0;
  1105.  
  1106.     /* Generic tags */
  1107.     if (!add_bi_record(BI_MACHTYPE, sizeof(bi.machtype), &bi.machtype))
  1108.     return(0);
  1109.     if (!add_bi_record(BI_CPUTYPE, sizeof(bi.cputype), &bi.cputype))
  1110.     return(0);
  1111.     if (!add_bi_record(BI_FPUTYPE, sizeof(bi.fputype), &bi.fputype))
  1112.     return(0);
  1113.     if (!add_bi_record(BI_MMUTYPE, sizeof(bi.mmutype), &bi.mmutype))
  1114.     return(0);
  1115.     for (i = 0; i < bi.num_memory; i++)
  1116.     if (!add_bi_record(BI_MEMCHUNK, sizeof(bi.memory[i]), &bi.memory[i]))
  1117.         return(0);
  1118.     if (bi.ramdisk.size)
  1119.     if (!add_bi_record(BI_RAMDISK, sizeof(bi.ramdisk), &bi.ramdisk))
  1120.         return(0);
  1121.     if (!add_bi_string(BI_COMMAND_LINE, bi.command_line))
  1122.     return(0);
  1123.  
  1124.     /* Amiga tags */
  1125.     if (!add_bi_record(BI_AMIGA_MODEL, sizeof(bi.model), &bi.model))
  1126.     return(0);
  1127.     for (i = 0; i < bi.num_autocon; i++)
  1128.     if (!add_bi_record(BI_AMIGA_AUTOCON, sizeof(bi.autocon[i]),
  1129.                 &bi.autocon[i]))
  1130.         return(0);
  1131.     if (!add_bi_record(BI_AMIGA_CHIP_SIZE, sizeof(bi.chip_size), &bi.chip_size))
  1132.     return(0);
  1133.     if (!add_bi_record(BI_AMIGA_VBLANK, sizeof(bi.vblank), &bi.vblank))
  1134.     return(0);
  1135.     if (!add_bi_record(BI_AMIGA_PSFREQ, sizeof(bi.psfreq), &bi.psfreq))
  1136.     return(0);
  1137.     if (!add_bi_record(BI_AMIGA_ECLOCK, sizeof(bi.eclock), &bi.eclock))
  1138.     return(0);
  1139.     if (!add_bi_record(BI_AMIGA_CHIPSET, sizeof(bi.chipset), &bi.chipset))
  1140.     return(0);
  1141.     if (!add_bi_record(BI_AMIGA_SERPER, sizeof(bi.serper), &bi.serper))
  1142.     return(0);
  1143.  
  1144.     /* Trailer */
  1145.     record = (struct bi_record *)((u_long)&bi_union.record+bi_size);
  1146.     record->tag = BI_LAST;
  1147.     bi_size += sizeof(bi_union.record.tag);
  1148.  
  1149.     return(1);
  1150. }
  1151.  
  1152.  
  1153.     /*
  1154.      *  Add a Record to the Bootinfo Structure
  1155.      */
  1156.  
  1157. static int add_bi_record(u_short tag, u_short size, const void *data)
  1158. {
  1159.     struct bi_record *record;
  1160.     u_int size2;
  1161.  
  1162.     size2 = (sizeof(struct bi_record)+size+3)&-4;
  1163.     if (bi_size+size2+sizeof(bi_union.record.tag) > MAX_BI_SIZE) {
  1164.     Puts("Can't add bootinfo record. Ask a wizard to enlarge me.\n");
  1165.     return(0);
  1166.     }
  1167.     record = (struct bi_record *)((u_long)&bi_union.record+bi_size);
  1168.     record->tag = tag;
  1169.     record->size = size2;
  1170.     memcpy(record->data, data, size);
  1171.     bi_size += size2;
  1172.     return(1);
  1173. }
  1174.  
  1175.  
  1176.     /*
  1177.      *  Add a String Record to the Bootinfo Structure
  1178.      */
  1179.  
  1180. static int add_bi_string(u_short tag, const u_char *s)
  1181. {
  1182.     return(add_bi_record(tag, strlen(s)+1, (void *)s));
  1183. }
  1184.  
  1185.  
  1186. #ifdef BOOTINFO_COMPAT_1_0
  1187.  
  1188.     /*
  1189.      *  Create the Bootinfo structure for backwards compatibility mode
  1190.      */
  1191.  
  1192. static int create_compat_bootinfo(void)
  1193. {
  1194.     u_int i;
  1195.  
  1196.     compat_bootinfo.machtype = bi.machtype;
  1197.     if (bi.cputype & CPU_68020)
  1198.     compat_bootinfo.cputype = COMPAT_CPU_68020;
  1199.     else if (bi.cputype & CPU_68030)
  1200.     compat_bootinfo.cputype = COMPAT_CPU_68030;
  1201.     else if (bi.cputype & CPU_68040)
  1202.     compat_bootinfo.cputype = COMPAT_CPU_68040;
  1203.     else if (bi.cputype & CPU_68060)
  1204.     compat_bootinfo.cputype = COMPAT_CPU_68060;
  1205.     else {
  1206.     Printf("CPU type 0x%08lx not supported by kernel\n", bi.cputype);
  1207.     return(0);
  1208.     }
  1209.     if (bi.fputype & FPU_68881)
  1210.     compat_bootinfo.cputype |= COMPAT_FPU_68881;
  1211.     else if (bi.fputype & FPU_68882)
  1212.     compat_bootinfo.cputype |= COMPAT_FPU_68882;
  1213.     else if (bi.fputype & FPU_68040)
  1214.     compat_bootinfo.cputype |= COMPAT_FPU_68040;
  1215.     else if (bi.fputype & FPU_68060)
  1216.     compat_bootinfo.cputype |= COMPAT_FPU_68060;
  1217.     else if (bi.fputype) {
  1218.     Printf("FPU type 0x%08lx not supported by kernel\n", bi.fputype);
  1219.     return(0);
  1220.     }
  1221.     compat_bootinfo.num_memory = bi.num_memory;
  1222.     if (compat_bootinfo.num_memory > COMPAT_NUM_MEMINFO) {
  1223.     Printf("Warning: using only %ld blocks of memory\n",
  1224.            COMPAT_NUM_MEMINFO);
  1225.     compat_bootinfo.num_memory = COMPAT_NUM_MEMINFO;
  1226.     }
  1227.     for (i = 0; i < compat_bootinfo.num_memory; i++) {
  1228.     compat_bootinfo.memory[i].addr = bi.memory[i].addr;
  1229.     compat_bootinfo.memory[i].size = bi.memory[i].size;
  1230.     }
  1231.     if (bi.ramdisk.size) {
  1232.     compat_bootinfo.ramdisk_size = (bi.ramdisk.size+1023)/1024;
  1233.     compat_bootinfo.ramdisk_addr = bi.ramdisk.addr;
  1234.     } else {
  1235.     compat_bootinfo.ramdisk_size = 0;
  1236.     compat_bootinfo.ramdisk_addr = 0;
  1237.     }
  1238.     strncpy(compat_bootinfo.command_line, bi.command_line, COMPAT_CL_SIZE);
  1239.     compat_bootinfo.command_line[COMPAT_CL_SIZE-1] = '\0';
  1240.  
  1241.     compat_bootinfo.bi_amiga.model = bi.model;
  1242.     compat_bootinfo.bi_amiga.num_autocon = bi.num_autocon;
  1243.     if (compat_bootinfo.bi_amiga.num_autocon > COMPAT_NUM_AUTO) {
  1244.     Printf("Warning: using only %ld AutoConfig devices\n",
  1245.            COMPAT_NUM_AUTO);
  1246.     compat_bootinfo.bi_amiga.num_autocon = COMPAT_NUM_AUTO;
  1247.     }
  1248.     for (i = 0; i < compat_bootinfo.bi_amiga.num_autocon; i++)
  1249.     compat_bootinfo.bi_amiga.autocon[i] = bi.autocon[i];
  1250.     compat_bootinfo.bi_amiga.chip_size = bi.chip_size;
  1251.     compat_bootinfo.bi_amiga.vblank = bi.vblank;
  1252.     compat_bootinfo.bi_amiga.psfreq = bi.psfreq;
  1253.     compat_bootinfo.bi_amiga.eclock = bi.eclock;
  1254.     compat_bootinfo.bi_amiga.chipset = bi.chipset;
  1255.     compat_bootinfo.bi_amiga.hw_present = 0;
  1256.     return(1);
  1257. }
  1258. #endif /* BOOTINFO_COMPAT_1_0 */
  1259.  
  1260.  
  1261.     /*
  1262.      *  Compare the Bootstrap and Kernel Versions
  1263.      */
  1264.  
  1265. static int check_bootinfo_version(const char *memptr)
  1266. {
  1267.     const struct bootversion *bv = (struct bootversion *)memptr;
  1268.     unsigned long version = 0;
  1269.     int i, kernel_major, kernel_minor, boots_major, boots_minor;
  1270.  
  1271.     if (bv->magic == BOOTINFOV_MAGIC)
  1272.     for (i = 0; bv->machversions[i].machtype != 0; ++i)
  1273.         if (bv->machversions[i].machtype == MACH_AMIGA) {
  1274.         version = bv->machversions[i].version;
  1275.         break;
  1276.         }
  1277.     if (!version)
  1278.     Puts("Kernel has no bootinfo version info, assuming 0.0\n");
  1279.  
  1280.     kernel_major = BI_VERSION_MAJOR(version);
  1281.     kernel_minor = BI_VERSION_MINOR(version);
  1282.     boots_major  = BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION);
  1283.     boots_minor  = BI_VERSION_MINOR(AMIGA_BOOTI_VERSION);
  1284.     Printf("Bootstrap's bootinfo version: %ld.%ld\n", boots_major,
  1285.        boots_minor);
  1286.     Printf("Kernel's bootinfo version   : %ld.%ld\n", kernel_major,
  1287.        kernel_minor);
  1288.  
  1289.     switch (kernel_major) {
  1290.     case BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION):
  1291.         if (kernel_minor > boots_minor) {
  1292.         Puts("Warning: Bootinfo version of bootstrap and kernel "
  1293.                "differ!\n");
  1294.         Puts("         Certain features may not work.\n");
  1295.         }
  1296.         break;
  1297.  
  1298. #ifdef BOOTINFO_COMPAT_1_0
  1299.     case BI_VERSION_MAJOR(COMPAT_AMIGA_BOOTI_VERSION):
  1300.         Puts("(using backwards compatibility mode)\n");
  1301.         break;
  1302. #endif /* BOOTINFO_COMPAT_1_0 */
  1303.  
  1304.     default:
  1305.         Printf("\nThis bootstrap is too %s for this kernel!\n",
  1306.            boots_major < kernel_major ? "old" : "new");
  1307.         return(0);
  1308.     }
  1309.     return(kernel_major);
  1310. }
  1311.  
  1312.  
  1313.     /*
  1314.      *    Call the copy-and-go-code
  1315.      */
  1316.  
  1317. static void start_kernel(void (*startfunc)(), char *stackp, char *memptr,
  1318.              u_long start_mem, u_long mem_size, u_long rd_size,
  1319.              u_long kernel_size)
  1320. {
  1321.     register void (*a0)() __asm("a0") = startfunc;
  1322.     register char *a2 __asm("a2") = stackp;
  1323.     register char *a3 __asm("a3") = memptr;
  1324.     register u_long a4 __asm("a4") = start_mem;
  1325.     register u_long d0 __asm("d0") = mem_size;
  1326.     register u_long d1 __asm("d1") = rd_size;
  1327.     register u_long d2 __asm("d2") = kernel_size;
  1328.     register u_long d3 __asm("d3") = bi_size;
  1329.  
  1330.     __asm __volatile ("movel a2,sp;"
  1331.               "jmp a0@"
  1332.               : /* no outputs */
  1333.               : "r" (a0), "r" (a2), "r" (a3), "r" (a4), "r" (d0),
  1334.             "r" (d1), "r" (d2), "r" (d3)
  1335.               /* no return */);
  1336.     /* fake a noreturn */
  1337.     for (;;);
  1338. }
  1339.  
  1340. asm(".text\n"
  1341. ".align 4\n"
  1342. SYMBOL_NAME_STR(_getvbr) ":
  1343.  movec vbr,d0
  1344.  rte
  1345. ");
  1346.  
  1347.  
  1348. /* LPSTOP cannot be used on the 68060. Apparently the 
  1349.    CyberStorm bus design cannot cope with it.*/
  1350. /* Just let the 68k hang for now. */
  1351. asm(".text\n"
  1352. ".align 4\n"
  1353. SYMBOL_NAME_STR(_wedgie) ":
  1354. stop #0x2700
  1355. ");
  1356.  
  1357.     /*
  1358.      *    This assembler code is copied to chip ram, and then executed.
  1359.      *    It copies the kernel to it's final resting place.
  1360.      *
  1361.      *    It is called with:
  1362.      *
  1363.      *        a3 = memptr
  1364.      *        a4 = start_mem
  1365.      *        d0 = mem_size
  1366.      *        d1 = rd_size
  1367.      *        d2 = kernel_size
  1368.      *        d3 = bi_size
  1369.      */
  1370.  
  1371. asm(".text\n"
  1372. ".align 4\n"
  1373. SYMBOL_NAME_STR(_copyall) ":
  1374.                 | /* copy kernel text and data */
  1375.     movel    a3,a0        | src = (u_long *)memptr;
  1376.     movel    a0,a2        | limit = (u_long *)(memptr+kernel_size);
  1377.     addl    d2,a2
  1378.     movel    a4,a1        | dest = (u_long *)start_mem;
  1379. 1:    cmpl    a0,a2
  1380.     jeq    2f        | while (src < limit)
  1381.     moveb    a0@+,a1@+    |  *dest++ = *src++;
  1382.     jra    1b
  1383. 2:
  1384.                 | /* copy bootinfo to end of bss */
  1385.     movel    a3,a0        | src = (u_long *)(memptr+kernel_size);
  1386.     addl    d2,a0        | dest = end of bss (already in a1)
  1387.     movel    d3,d7        | count = bi_size
  1388.     subql    #1,d7
  1389. 1:    moveb    a0@+,a1@+    | while (--count > -1)
  1390.     dbra    d7,1b        |     *dest++ = *src++
  1391.  
  1392.                 | /* copy the ramdisk to the top of memory */
  1393.                 | /* (from back to front) */
  1394.     movel    a4,a1        | dest = (u_long *)(start_mem+mem_size);
  1395.     addl    d0,a1
  1396.     movel    a3,a2        | limit = (u_long *)(memptr+kernel_size +
  1397.     addl    d2,a2        |             bi_size);
  1398.     addl    d3,a2
  1399.     movel    a2,a0        | src = (u_long *)((u_long)limit+rd_size);
  1400.     addl    d1,a0
  1401. 1:    cmpl    a0,a2
  1402.     beqs    2f        | while (src > limit)
  1403.     moveb    a0@-,a1@-    |     *--dest = *--src;
  1404.     bras    1b
  1405. 2:
  1406.                 | /* jump to start of kernel */
  1407.     movel    a4,a0        | jump_to (start_mem);
  1408.     jmp    a0@
  1409. "
  1410. SYMBOL_NAME_STR(_copyallend) ":
  1411. ");
  1412.  
  1413.  
  1414.     /*
  1415.      *    Test for a MapROMmed A3640 Board
  1416.      */
  1417.  
  1418. asm(".text\n"
  1419. ".align 4\n"
  1420. SYMBOL_NAME_STR(_maprommed) ":
  1421.     oriw    #0x0700,sr
  1422.     moveml    #0x3f20,sp@-
  1423.                 | /* Save cache settings */
  1424.     .long    0x4e7a1002    | movec cacr,d1 */
  1425.                 | /* Save MMU settings */
  1426.     .long    0x4e7a2003    | movec tc,d2
  1427.     .long    0x4e7a3004    | movec itt0,d3
  1428.     .long    0x4e7a4005    | movec itt1,d4
  1429.     .long    0x4e7a5006    | movec dtt0,d5
  1430.     .long    0x4e7a6007    | movec dtt1,d6
  1431.     moveq    #0,d0
  1432.     movel    d0,a2
  1433.                 | /* Disable caches */
  1434.     .long    0x4e7b0002    | movec d0,cacr
  1435.                 | /* Disable MMU */
  1436.     .long    0x4e7b0003    | movec d0,tc
  1437.     .long    0x4e7b0004    | movec d0,itt0
  1438.     .long    0x4e7b0005    | movec d0,itt1
  1439.     .long    0x4e7b0006    | movec d0,dtt0
  1440.     .long    0x4e7b0007    | movec d0,dtt1
  1441.     lea    0x07f80000,a0
  1442.     lea    0x00f80000,a1
  1443.     movel    a0@,d7
  1444.     cmpl    a1@,d7
  1445.     jne    1f
  1446.     movel    d7,d0
  1447.     notl    d0
  1448.     movel    d0,a0@
  1449.     nop            | /* Thanks to Jörg Mayer! */
  1450.     cmpl    a1@,d0
  1451.     jne    1f
  1452.     moveq    #-1,d0        | /* MapROMmed A3640 present */
  1453.     movel    d0,a2
  1454. 1:    movel    d7,a0@
  1455.                 | /* Restore MMU settings */
  1456.     .long    0x4e7b2003    | movec d2,tc
  1457.     .long    0x4e7b3004    | movec d3,itt0
  1458.     .long    0x4e7b4005    | movec d4,itt1
  1459.     .long    0x4e7b5006    | movec d5,dtt0
  1460.     .long    0x4e7b6007    | movec d6,dtt1
  1461.                 | /* Restore cache settings */
  1462.     .long    0x4e7b1002    | movec d1,cacr
  1463.     movel    a2,d0
  1464.     moveml    sp@+,#0x04fc
  1465.     rte
  1466. ");
  1467.  
  1468.  
  1469.     /*
  1470.      *    Reset functions for nasty Zorro boards
  1471.      */
  1472.  
  1473. static void reset_rb3(const struct ConfigDev *cd)
  1474. {
  1475.     volatile u_char *rb3_reg = (u_char *)(cd->cd_BoardAddr+0x01002000);
  1476.  
  1477.     /* FN: If a Rainbow III board is present, reset it to disable */
  1478.     /* its (possibly activated) vertical blank interrupts as the */
  1479.     /* kernel is not yet prepared to handle them (level 6). */
  1480.  
  1481.     /* set RESET bit in special function register */
  1482.     *rb3_reg = 0x01;
  1483.     /* actually, only a few cycles delay are required... */
  1484.     Sleep(1000000);
  1485.     /* clear reset bit */
  1486.     *rb3_reg = 0x00;
  1487. }
  1488.  
  1489. static void reset_piccolo(const struct ConfigDev *cd)
  1490. {
  1491.     volatile u_char *piccolo_reg = (u_char *)(cd->cd_BoardAddr+0x8000);
  1492.  
  1493.     /* FN: the same stuff as above, for the Piccolo board. */
  1494.     /* this also has the side effect of resetting the board's */
  1495.     /* output selection logic to use the Amiga's display in single */
  1496.     /* monitor systems - which is currently what we want. */
  1497.  
  1498.     /* set RESET bit in special function register */
  1499.     *piccolo_reg = 0x01;
  1500.     /* actually, only a few cycles delay are required... */
  1501.     Sleep(1000000);
  1502.     /* clear reset bit */
  1503.     *piccolo_reg = 0x51;
  1504. }
  1505.  
  1506. static void reset_sd64(const struct ConfigDev *cd)
  1507. {
  1508.     volatile u_char *sd64_reg = (u_char *)(cd->cd_BoardAddr+0x8000);
  1509.  
  1510.     /* FN: the same stuff as above, for the SD64 board. */
  1511.     /* just as on the Piccolo, this also resets the monitor switch */
  1512.  
  1513.     /* set RESET bit in special function register */
  1514.     *sd64_reg = 0x1f;
  1515.     /* actually, only a few cycles delay are required... */
  1516.     Sleep(1000000);
  1517.     /* clear reset bit AND switch monitor bit (0x20) */
  1518.     *sd64_reg = 0x4f;
  1519. }
  1520.  
  1521. static void reset_a2065(const struct ConfigDev *cd)
  1522. {
  1523.     volatile u_short *lance_rdp = (u_short *)(cd->cd_BoardAddr+0x4000);
  1524.     volatile u_short *lance_rap = (u_short *)(cd->cd_BoardAddr+0x4002);
  1525.  
  1526.     Disable();
  1527.  
  1528.     /* Stop the card */
  1529.     *lance_rap = 0; /* PCnet-ISA Controller Status (CSR0) */
  1530.     *lance_rdp = 4; /* STOP */
  1531.  
  1532.     Enable();
  1533. }
  1534.     
  1535. static void reset_ariadne(const struct ConfigDev *cd)
  1536. {
  1537.     volatile u_short *lance_rdp = (u_short *)(cd->cd_BoardAddr+0x0370);
  1538.     volatile u_short *lance_rap = (u_short *)(cd->cd_BoardAddr+0x0372);
  1539.     volatile u_short *lance_reset = (u_short *)(cd->cd_BoardAddr+0x0374);
  1540.  
  1541.     volatile u_char *pit_paddr = (u_char *)(cd->cd_BoardAddr+0x1004);
  1542.     volatile u_char *pit_pbddr = (u_char *)(cd->cd_BoardAddr+0x1006);
  1543.     volatile u_char *pit_pacr = (u_char *)(cd->cd_BoardAddr+0x100b);
  1544.     volatile u_char *pit_pbcr = (u_char *)(cd->cd_BoardAddr+0x100e);
  1545.     volatile u_char *pit_psr = (u_char *)(cd->cd_BoardAddr+0x101a);
  1546.  
  1547.     u_short in;
  1548.  
  1549.     Disable();
  1550.  
  1551.     /*
  1552.      *    Reset the Ethernet part (Am79C960 PCnet-ISA)
  1553.      */
  1554.  
  1555.     in = *lance_reset;   /* Reset Chip on Read Access */
  1556.     *lance_rap = 0x0000; /* PCnet-ISA Controller Status (CSR0) */
  1557.     *lance_rdp = 0x0400; /* STOP */
  1558.  
  1559.     /*
  1560.      *    Reset the Parallel part (MC68230 PI/T)
  1561.      */
  1562.  
  1563.     *pit_pacr &= 0xfd;   /* Port A Control Register */
  1564.     *pit_pbcr &= 0xfd;   /* Port B Control Register */
  1565.     *pit_psr = 0x05;     /* Port Status Register */
  1566.     *pit_paddr = 0x00;   /* Port A Data Direction Register */
  1567.     *pit_pbddr = 0x00;   /* Port B Data Direction Register */
  1568.  
  1569.     Enable();
  1570. }
  1571.  
  1572. static void reset_hydra(const struct ConfigDev *cd)
  1573. {
  1574.     volatile u_char *nic_cr  = (u_char *)(cd->cd_BoardAddr+0xffe1);
  1575.     volatile u_char *nic_isr = (u_char *)(cd->cd_BoardAddr+0xffe1 + 14);
  1576.     int n = 5000;
  1577.  
  1578.     Disable();
  1579.  
  1580.     *nic_cr = 0x21;    /* nic command register: software reset etc. */
  1581.     while (((*nic_isr & 0x80) == 0) && --n)  /* wait for reset to complete */
  1582.     ;
  1583.  
  1584.     Enable();
  1585. }
  1586.  
  1587. #if 0
  1588. static void reset_a2060(const struct ConfigDev *cd)
  1589. {
  1590. #error reset_a2060: not yet implemented
  1591. }
  1592. #endif
  1593.  
  1594.  
  1595. #ifdef ZKERNEL
  1596.  
  1597. #define    ZFILE_CHUNK_BITS    16  /* chunk is 64 KB */
  1598. #define    ZFILE_CHUNK_SIZE    (1 << ZFILE_CHUNK_BITS)
  1599. #define    ZFILE_CHUNK_MASK    (ZFILE_CHUNK_SIZE-1)
  1600. #define    ZFILE_N_CHUNKS        (2*1024*1024/ZFILE_CHUNK_SIZE)
  1601.  
  1602. /* variables for storing the uncompressed data */
  1603. static char *ZFile[ZFILE_N_CHUNKS];
  1604. static int ZFileSize = 0;
  1605. static int ZFpos = 0;
  1606. static int Zwpos = 0;
  1607.  
  1608. static int Zinfd = 0;         /* fd of compressed file */
  1609.  
  1610. /*
  1611.  * gzip declarations
  1612.  */
  1613.  
  1614. #define OF(args)  args
  1615.  
  1616. #define memzero(s, n)     memset ((s), 0, (n))
  1617.  
  1618. typedef unsigned char  uch;
  1619. typedef unsigned short ush;
  1620. typedef unsigned long  ulg;
  1621.  
  1622. #define INBUFSIZ 4096
  1623. #define WSIZE 0x8000    /* window size--must be a power of two, and */
  1624.             /*  at least 32K for zip's deflate method */
  1625.  
  1626. static uch *inbuf;
  1627. static uch *window;
  1628.  
  1629. static unsigned insize = 0;  /* valid bytes in inbuf */
  1630. static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
  1631. static unsigned outcnt = 0;  /* bytes in output buffer */
  1632. static int exit_code = 0;
  1633. static long bytes_out = 0;
  1634.  
  1635. #define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
  1636.         
  1637. /* Diagnostic functions (stubbed out) */
  1638. #define Assert(cond,msg)
  1639. #define Trace(x)
  1640. #define Tracev(x)
  1641. #define Tracevv(x)
  1642. #define Tracec(c,x)
  1643. #define Tracecv(c,x)
  1644.  
  1645. #define STATIC static
  1646.  
  1647. static int  fill_inbuf(void);
  1648. static void flush_window(void);
  1649. static void error(char *m);
  1650. static void gzip_mark(void **);
  1651. static void gzip_release(void **);
  1652.  
  1653. #define malloc(x)    AllocVec(x, MEMF_FAST | MEMF_PUBLIC)
  1654. #define free(x)        FreeVec(x)
  1655.  
  1656. #ifdef LILO
  1657. #include "inflate.c"
  1658. #else
  1659. #include "../../../../lib/inflate.c"
  1660. #endif
  1661.  
  1662. static void gzip_mark(void **ptr)
  1663. {
  1664. }
  1665.  
  1666. static void gzip_release(void **ptr)
  1667. {
  1668. }
  1669.  
  1670.  
  1671. /*
  1672.  * Fill the input buffer. This is called only when the buffer is empty
  1673.  * and at least one byte is really needed.
  1674.  */
  1675. static int fill_inbuf(void)
  1676. {
  1677.     if (exit_code)
  1678.     return -1;
  1679.  
  1680.     insize = Read(Zinfd, inbuf, INBUFSIZ);
  1681.     if (insize <= 0)
  1682.     return -1;
  1683.  
  1684.     inptr = 1;
  1685.     return(inbuf[0]);
  1686. }
  1687.  
  1688. /*
  1689.  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
  1690.  * (Used for the decompressed data only.)
  1691.  */
  1692. static void flush_window(void)
  1693. {
  1694.     ulg c = crc;         /* temporary variable */
  1695.     unsigned n;
  1696.     uch *in, ch;
  1697.     int chunk = Zwpos >> ZFILE_CHUNK_BITS;
  1698.  
  1699.     if (exit_code)
  1700.     return;
  1701.  
  1702.     if (chunk >= ZFILE_N_CHUNKS) {
  1703.     error("Compressed image too large! Aborting.\n");
  1704.     return;
  1705.     }
  1706.     if (!ZFile[chunk]) {
  1707.     if (!(ZFile[chunk] = (char *)AllocMem(ZFILE_CHUNK_SIZE,
  1708.                           MEMF_FAST | MEMF_PUBLIC))) {
  1709.         error("Out of memory for decompresing kernel image\n");
  1710.         return;
  1711.     }
  1712.     }
  1713.     memcpy(ZFile[chunk] + (Zwpos & ZFILE_CHUNK_MASK), window, outcnt);
  1714.     Zwpos += outcnt;
  1715.     
  1716. #define    DISPLAY_BITS 10
  1717.     if ((Zwpos & ((1 << DISPLAY_BITS)-1)) == 0)
  1718.     PutChar('.');
  1719.     
  1720.     in = window;
  1721.     for (n = 0; n < outcnt; n++) {
  1722.     ch = *in++;
  1723.     c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
  1724.     }
  1725.     crc = c;
  1726.     bytes_out += (ulg)outcnt;
  1727.     outcnt = 0;
  1728. }
  1729.  
  1730. static void error(char *x)
  1731. {
  1732.     Printf("\n%s", x);
  1733.     exit_code = 1;
  1734. }
  1735.  
  1736. static inline int call_sub(int (*func)(void), void *stackp)
  1737. {
  1738.     register int _res __asm("d0");
  1739.     register int (*a0)(void) __asm("a0") = func;
  1740.     register int (*a1)(void) __asm("a1") = stackp;
  1741.  
  1742.     __asm __volatile ("movel sp,a2;"
  1743.                   "movel a1,sp;"
  1744.                   "jsr a0@;"
  1745.                   "movel a2,sp"
  1746.               : "=r" (_res)
  1747.               : "r" (a0), "r" (a1)
  1748.               : "a0", "a1", "a2", "d0", "d1", "memory");
  1749.     return(_res);
  1750. }
  1751.  
  1752. static int load_zkernel(int fd)
  1753. {
  1754.     int i, err = -1;
  1755. #define ZSTACKSIZE    (16384)
  1756.     u_long *zstack;
  1757.     
  1758.     for (i = 0; i < ZFILE_N_CHUNKS; ++i)
  1759.     ZFile[i] = NULL;
  1760.     Zinfd = fd;
  1761.     Seek(fd, 0);
  1762.     
  1763.     if (!(inbuf = (uch *)AllocMem(INBUFSIZ, MEMF_FAST | MEMF_PUBLIC)))
  1764.     Puts("Couldn't allocate gunzip buffer\n");
  1765.     else {
  1766.     if (!(window = (uch *)AllocMem(WSIZE, MEMF_FAST | MEMF_PUBLIC)))
  1767.         Puts("Couldn't allocate gunzip window\n");
  1768.     else {
  1769.         if (!(zstack = (u_long *)AllocMem(ZSTACKSIZE,
  1770.                               MEMF_FAST | MEMF_PUBLIC)))
  1771.         Puts("Couldn't allocate gunzip stack\n");
  1772.         else {
  1773.         Puts("Uncompressing kernel image ");
  1774.         makecrc();
  1775.         if (!(err = call_sub(gunzip, (char *)zstack+ZSTACKSIZE)))
  1776.             Puts("done\n");
  1777.         ZFileSize = Zwpos;
  1778.         FreeMem(zstack, ZSTACKSIZE);
  1779.         }
  1780.         FreeMem(window, WSIZE);
  1781.         window = NULL;
  1782.     }
  1783.     FreeMem(inbuf, INBUFSIZ);
  1784.     inbuf = NULL;
  1785.     }
  1786.     Close(Zinfd);    /* input file not needed anymore */
  1787.     return(err);
  1788. }
  1789.  
  1790.  
  1791. /* Note about the read/lseek wrapper and its memory management: It assumes
  1792.  * that all seeks are only forward, and thus data already read or skipped can
  1793.  * be freed. This is true for current organization of bootstrap and kernels.
  1794.  * Little exception: The struct kexec at the start of the file. After reading
  1795.  * it, there may be a seek back to the end of the file. But this currently
  1796.  * doesn't hurt. (Roman)
  1797.  */
  1798.  
  1799. static int KRead(int fd, void *buf, int cnt)
  1800. {
  1801.     unsigned done = 0;
  1802.     
  1803.     if (!ZFileSize)
  1804.     return(Read(fd, buf, cnt));
  1805.     
  1806.     if (ZFpos + cnt > ZFileSize)
  1807.     cnt = ZFileSize - ZFpos;
  1808.     
  1809.     while (cnt > 0) {
  1810.     unsigned chunk = ZFpos >> ZFILE_CHUNK_BITS;
  1811.     unsigned endchunk = (chunk+1) << ZFILE_CHUNK_BITS;
  1812.     unsigned n = cnt;
  1813.  
  1814.     if (ZFpos + n > endchunk)
  1815.         n = endchunk - ZFpos;
  1816.     memcpy(buf, ZFile[chunk] + (ZFpos & ZFILE_CHUNK_MASK), n);
  1817.     cnt -= n;
  1818.     buf += n;
  1819.     done += n;
  1820.     ZFpos += n;
  1821.  
  1822.     if (ZFpos == endchunk) {
  1823.         FreeMem(ZFile[chunk], ZFILE_CHUNK_SIZE);
  1824.         ZFile[chunk] = NULL;
  1825.     }
  1826.     }
  1827.  
  1828.     return(done);
  1829. }
  1830.  
  1831.  
  1832. static int KSeek(int fd, int offset)
  1833. {
  1834.     unsigned oldpos, oldchunk, newchunk;
  1835.  
  1836.     if (!ZFileSize)
  1837.     return(Seek(fd, offset));
  1838.  
  1839.     oldpos = ZFpos;
  1840.     ZFpos = offset;
  1841.     if (ZFpos < 0) {
  1842.     ZFpos = 0;
  1843.     return(-1);
  1844.     } else if (ZFpos > ZFileSize) {
  1845.     ZFpos = ZFileSize;
  1846.     return(-1);
  1847.     }
  1848.  
  1849.     /* free memory of skipped-over data */
  1850.     oldchunk = oldpos >> ZFILE_CHUNK_BITS;
  1851.     newchunk = ZFpos  >> ZFILE_CHUNK_BITS;
  1852.     while(oldchunk < newchunk) {
  1853.     if (ZFile[oldchunk]) {
  1854.         FreeMem(ZFile[oldchunk], ZFILE_CHUNK_SIZE);
  1855.         ZFile[oldchunk] = NULL;
  1856.     }
  1857.     ++oldchunk;
  1858.     }
  1859.     return(ZFpos);
  1860. }
  1861.  
  1862.  
  1863. static void free_zfile(void)
  1864. {
  1865.     int i;
  1866.  
  1867.     for (i = 0; i < ZFILE_N_CHUNKS; ++i)
  1868.     if (ZFile[i]) {
  1869.         FreeMem(ZFile[i], ZFILE_CHUNK_SIZE);
  1870.         ZFile[i] = NULL;
  1871.     }
  1872. }
  1873.  
  1874. static int KClose(int fd)
  1875. {
  1876.     if (ZFileSize) {
  1877.     free_zfile();
  1878.     ZFileSize = 0;
  1879.     } else
  1880.     Close(fd);
  1881.     return(0);
  1882. }
  1883. #endif /* ZKERNEL */
  1884.